package com.dongxing.concyrrency.chapter9;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author XavierDong
 **/
public class CaptureService {


    private final static LinkedList<Control> controls = new LinkedList<>();
    private final static Integer MAX_WORKER = 5;


    public static void main(String[] args) {

        List<Thread> worker = new ArrayList<>();

        Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10").stream()
                .map(CaptureService::createThread)
                .forEach(t -> {
                    t.start();
                    worker.add(t);
                });

        worker.forEach(CaptureService::join);
        Optional.of("All of capture work finished.").ifPresent(System.out::println);


    }

    private static Thread createThread(final String name) {
        return new Thread(() -> {

            Optional.of("The Worker [" + Thread.currentThread().getName() + "] begin capture data.").ifPresent(System.out::println);

            synchronized (controls) {
                while (controls.size() > MAX_WORKER) {
                    try {
                        controls.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Thread.currentThread().interrupt();
                    }
                }
                // 进行数据保护
                controls.addLast(new Control());
            }

            // 正常工作
            Optional.of("The worker [" + Thread.currentThread().getName() + "] is working....").ifPresent(System.out::println);
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }

            synchronized (controls) {
                Optional.of("The worker [" + Thread.currentThread().getName() + "] End capture data.").ifPresent(System.out::println);
                controls.removeFirst();
                controls.notifyAll();
            }
        }, name);
    }

    private static void join(Thread t) {
        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }


    private static class Control {

    }


}
